package jk.fox.invocation.invoker;

import jk.fox.common.ReflectionUtils;
import org.apache.log4j.Logger;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author cuichao
 * @Description: RpcInvoker
 * @Date: create in 2020/4/13 15:13
 */
public class RpcInvoker implements Invoker {

    private static Logger logger = Logger.getLogger(RpcInvoker.class);


    protected final Map<String,Method> methodPool = new ConcurrentHashMap<>(256);

    /**
     * 目前invoker类 有java 反射实现 由于性能和GC问题,
     * 做了方法池化但不能治本,后期可以通过javassist-asm
     * 通过字节码调用方式改善性能
     * @param target
     * @param method
     * @param parameters
     * @return
     * @throws Exception
     */
    @Override
    public Object invoke(Object target, Method method,Object[] parameters) throws Exception {
        Object object= method.invoke(target,parameters);
        return object;
    }

    @Override
    public Object invoke(Object target, String method,String[] parameterTypes, Object[] parameters) throws Exception{
        String methodKey;
        String classKey = target.getClass().getName();

        String parameterKey = Arrays.stream(parameterTypes).reduce(null, (k, v) -> {
            if (k == null) {
                return v;
            }
            return k + "-" + v;
        });

        methodKey = classKey+"-"+method+"-"+parameterKey;
        Method targetMethod = methodPool.get(methodKey);
        if(targetMethod == null ){
            targetMethod = ReflectionUtils.searchMethod(target, method,parameterTypes);
            methodPool.put(methodKey,targetMethod);
        }
        logger.info("remote method by key: "+methodKey);
        Object object= invoke(target,targetMethod,parameters);
        return object;
    }



}
